#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

typedef void (*func_t) ();

#define NUM 5
func_t handlers[NUM+1];

// 任务
void DownLoad()
{
    printf("我是一个下载任务...\n");
}

void Flush()
{
    printf("我是一个刷新任务...\n");
}

void Log()
{
    printf("我是一个记录任务...\n");
}

// 注册
void  registerHandler(func_t handlers[], func_t fun)
{
    int i = 0;
    for(i = 0; i < NUM; ++i)
    {
        if(handlers[i] == NULL)
            break;
    }
    if (i == NUM)
        return;
    handlers[i] = fun;
    handlers[i+1] = NULL;
}

int main()
{
    registerHandler(handlers, DownLoad);
    registerHandler(handlers, Flush);
    registerHandler(handlers, Log);

    pid_t id = fork();

    if(id == 0)
    {
        // 子进程
        while(1)
        {
            printf("我是一个子进程, pid: %d, ppid: %d\n", getpid(), getppid());
            sleep(1);
        }
        exit(10);
    }

    while(1)
    {
        int status = 0;
        pid_t rid = waitpid(id, &status, WNOHANG);
        if(rid > 0)
        {
            printf("wait sucess, rid: %d. exit code: %d, exit signal: %d\n", rid, WEXITSTATUS(status), WTERMSIG(status));
            break;
        }
        else if(rid == 0)
        {
            for(int i = 0; handlers[i]; ++i)
            {
                handlers[i]();
            }
            printf("本轮调用结束,子进程未退出\n");
            sleep(1);
        }
        else 
        {
            printf("wait failed");
            break;
        }
    }

    // 父进程
   // int status = 0;
   // pid_t rid = waitpid(id, &status, 0);
   // if(rid > 0)
   // {
   //     printf("父进程等待子进程成功，子进程pid：%d\n", rid);

   //     if (WIFEXITED(status))   // 判断子进程是否正常退出
   //     printf("子进程正常退出，退出码：%d\n", WEXITSTATUS(status));
   //     else if (WIFSIGNALED(status)) // 判断子进程是否被信号终止
   //     printf("子进程被信号终止，终止信号：%d\n", WTERMSIG(status));
   // }
   // else 
   // {
   //     printf("wait failed: %d: %s\n", errno, strerror(errno));
   // }


    return 0;
}
//void func()
//{
//    printf("fun begin\n");
//    _exit(4);
//    printf("fun end\n");
//}

//int main()
//{
//    
//    //func();
//    printf("main()");
//    sleep(2);
//    _exit(23);
//    
//    
//    //int a = 10;
//    //a /= 0;
//
//    
//    
//    //for(int i = 0; i < 134; ++i)
//    //{
//    //    printf("%d -> %s\n", i, strerror(i));
//    //}
//
//    ////printf("hello world\n");
//
//    //FILE *fp = fopen("log.txt", "r");
//
//    //if(fp == NULL) return errno;
//
//
//    //fclose(fp);
//
//    return 0;
//}
